import {
  Injectable,
  NotFoundException,
  ConflictException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Album } from './album.entity';
import {
  CreateAlbumDto,
  UpdateAlbumDto,
  AlbumResponseDto,
  AlbumsPaginationQueryDto,
} from './album.dto';
import { PaginationResponseDto } from '../song/song.dto';
import { Singer } from '../singer/singer.entity';
import { Song } from '../song/song.entity';

@Injectable()
export class AlbumService {
  constructor(
    @InjectRepository(Album)
    private albumRepository: Repository<Album>,
    @InjectRepository(Singer)
    private singerRepository: Repository<Singer>,
    @InjectRepository(Song)
    private songRepository: Repository<Song>,
  ) {}

  // 将专辑实体映射为响应DTO
  private mapToResponseDto(album: Album): AlbumResponseDto {
    const dto = new AlbumResponseDto();
    dto.id = album.id;
    dto.title = album.title;
    dto.artist = {
      id: album.artist.id,
      name: album.artist.name,
    };
    dto.releaseDate = album.releaseDate;
    dto.coverImageUrl = album.coverImageUrl;
    dto.description = album.description;
    dto.plays = album.plays;
    dto.createdAt = album.createdAt;
    dto.updatedAt = album.updatedAt;

    // 映射歌曲列表 - 保留必填的歌手信息，移除重复的专辑信息
    dto.songs =
      album.songs?.map((song) => ({
        id: song.id,
        title: song.title,
        artist: {
          id: song.artist.id,
          name: song.artist.name,
        },
        genre: song.genre,
        duration: song.duration,
        audioUrl: song.audioUrl,
        coverImageUrl: song.coverImageUrl,
        lyrics: song.lyrics,
        plays: song.plays,
        likes: song.likes || 0,
        createdAt: song.createdAt,
        updatedAt: song.updatedAt,
        uploadedBy: song.uploadedBy
          ? {
              id: song.uploadedBy.id,
              username: song.uploadedBy.username,
            }
          : undefined,
        categories:
          song.categories?.map((category) => ({
            id: category.id,
            name: category.name,
          })) || [],
      })) || [];

    return dto;
  }

  // 创建新专辑
  async createAlbum(createAlbumDto: CreateAlbumDto): Promise<AlbumResponseDto> {
    // 检查专辑名称是否已存在
    const existingAlbum = await this.albumRepository.findOneBy({
      title: createAlbumDto.title,
    });
    if (existingAlbum) {
      throw new ConflictException(`专辑名称 "${createAlbumDto.title}" 已存在`);
    }

    // 检查歌手是否存在
    const singer = await this.singerRepository.findOneBy({
      id: createAlbumDto.artistId,
    });
    if (!singer) {
      throw new NotFoundException(`歌手ID ${createAlbumDto.artistId} 不存在`);
    }

    const album = this.albumRepository.create({
      ...createAlbumDto,
      artist: singer,
      releaseDate: createAlbumDto.releaseDate
        ? new Date(createAlbumDto.releaseDate)
        : undefined,
    });
    const savedAlbum = await this.albumRepository.save(album);
    return this.mapToResponseDto(savedAlbum);
  }

  // 获取所有专辑（无分页版本，保持向后兼容）
  async getAllAlbums(): Promise<AlbumResponseDto[]> {
    const albums = await this.albumRepository.find({
      relations: ['artist'],
      order: { createdAt: 'DESC' },
    });
    return albums.map((album) => this.mapToResponseDto(album));
  }

  // 获取专辑列表（支持分页）
  async findAlbumsWithPagination(
    queryDto: AlbumsPaginationQueryDto,
  ): Promise<PaginationResponseDto<AlbumResponseDto>> {
    const { page = 1, limit = 10, searchTerm } = queryDto;
    const skip = (page - 1) * limit;

    // 查询构建
    const query = this.albumRepository
      .createQueryBuilder('album')
      .leftJoinAndSelect('album.artist', 'artist')
      .orderBy('album.createdAt', 'DESC')
      .skip(skip)
      .take(limit);

    // 如果提供了搜索关键词，添加搜索条件
    if (searchTerm) {
      query.where(
        'album.title LIKE :searchTerm OR artist.name LIKE :searchTerm',
        {
          searchTerm: `%${searchTerm}%`,
        },
      );
    }

    // 执行查询
    const [albums, total] = await query.getManyAndCount();

    // 计算分页元数据
    const totalPages = Math.ceil(total / limit);
    const hasNextPage = page < totalPages;
    const hasPreviousPage = page > 1;

    return {
      data: albums.map((album) => this.mapToResponseDto(album)),
      meta: {
        total,
        page,
        limit,
        totalPages,
        hasNextPage,
        hasPreviousPage,
      },
    };
  }

  // 获取单个专辑（包含歌曲列表）
  async getAlbumById(id: number): Promise<AlbumResponseDto> {
    const album = await this.albumRepository.findOne({
      where: { id },
      relations: [
        'artist',
        'songs',
        'songs.artist',
        'songs.categories',
        'songs.uploadedBy',
      ],
    });
    if (!album) {
      throw new NotFoundException(`专辑ID ${id} 不存在`);
    }
    return this.mapToResponseDto(album);
  }

  // 获取专辑及其歌曲列表
  async getAlbumWithSongs(id: number): Promise<AlbumResponseDto> {
    return this.getAlbumById(id);
  }

  // 更新专辑
  async updateAlbum(
    id: number,
    updateAlbumDto: UpdateAlbumDto,
  ): Promise<AlbumResponseDto> {
    const album = await this.albumRepository.findOne({
      where: { id },
      relations: ['artist'],
    });
    if (!album) {
      throw new NotFoundException(`专辑ID ${id} 不存在`);
    }

    // 检查新的专辑名称是否已存在（如果提供了新名称）
    if (updateAlbumDto.title && updateAlbumDto.title !== album.title) {
      const existingAlbum = await this.albumRepository.findOneBy({
        title: updateAlbumDto.title,
      });
      if (existingAlbum) {
        throw new ConflictException(
          `专辑名称 "${updateAlbumDto.title}" 已存在`,
        );
      }
    }

    // 如果提供了新的歌手ID，检查歌手是否存在
    if (
      updateAlbumDto.artistId &&
      updateAlbumDto.artistId !== album.artist.id
    ) {
      const singer = await this.singerRepository.findOneBy({
        id: updateAlbumDto.artistId,
      });
      if (!singer) {
        throw new NotFoundException(`歌手ID ${updateAlbumDto.artistId} 不存在`);
      }
      album.artist = singer;
    }

    // 更新专辑信息
    Object.assign(album, {
      ...updateAlbumDto,
      releaseDate: updateAlbumDto.releaseDate
        ? new Date(updateAlbumDto.releaseDate)
        : album.releaseDate,
    });
    const updatedAlbum = await this.albumRepository.save(album);
    return this.mapToResponseDto(updatedAlbum);
  }

  // 删除专辑
  async deleteAlbum(id: number): Promise<void> {
    const result = await this.albumRepository.delete(id);
    if (result.affected === 0) {
      throw new NotFoundException(`专辑ID ${id} 不存在`);
    }
  }

  // 获取专辑的所有歌曲
  async getSongsByAlbum(id: number): Promise<Song[]> {
    const album = await this.albumRepository.findOne({
      where: { id },
      relations: ['songs'],
    });
    if (!album) {
      throw new NotFoundException(`专辑ID ${id} 不存在`);
    }
    return album.songs;
  }

  // 根据歌手获取专辑
  async getAlbumsBySinger(singerId: number): Promise<AlbumResponseDto[]> {
    const albums = await this.albumRepository.find({
      where: { artist: { id: singerId } },
      relations: ['artist'],
      order: { releaseDate: 'DESC' },
    });
    return albums.map((album) => this.mapToResponseDto(album));
  }

  // 搜索专辑
  async searchAlbums(keyword: string): Promise<AlbumResponseDto[]> {
    const albums = await this.albumRepository
      .createQueryBuilder('album')
      .leftJoinAndSelect('album.artist', 'artist')
      .where('album.title LIKE :keyword', { keyword: `%${keyword}%` })
      .orWhere('album.description LIKE :keyword', { keyword: `%${keyword}%` })
      .getMany();
    return albums.map((album) => this.mapToResponseDto(album));
  }
}
